/*
** strace.c for  in /home/lund/Projets/SysUnixAv/seutrace
** 
** Made by florian dewulf
** Login   <dewulf_f@epitech.net>
** 
** Started on  Tue Apr 30 16:27:45 2013 florian dewulf
** Last update Fri May 17 17:45:33 2013 kevin lansel
*/

#include	<stdio.h>
#include	<stdlib.h>
#include	<sys/types.h>
#include	<sys/wait.h>
#include	<sys/user.h>
#include	<sys/ptrace.h>
#include	<unistd.h>
#include	"strace.h"

static void	trace_prog(int pid)
{
  struct user_regs_struct	registre;
  int				status;
  unsigned long	long		*value;
  t_syscall			sys;

  while (waitpid(pid, &status, 0) != -1 && !WIFEXITED(status))
    {
      ptrace(PTRACE_GETREGS, pid, NULL, &registre);
      if ((int)registre.orig_rax >= 0 && is_syscall(registre.orig_rax))
	{
	  sys = which_syscall(registre.orig_rax);
	  value = xmalloc((size_tab(sys.arg) + 1) * sizeof(unsigned long));
	  fill_tab(value, &sys, &registre);
	  loop_ptr_func(value, &sys, &registre, pid);
	}
      ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL);
    }
}

void		strace_arg(char *arg)
{
  int		pid;

  pid = atoi(arg);
  ptrace(PTRACE_ATTACH, pid, 0, 0);
  trace_prog(pid);
}

void		strace_noarg(char *arg)
{
  int		pid;

  pid = fork();
  if (pid == -1)
    {
      printf("Error on fork\n");
      return;
    }
  if (pid == 0)
    {
      ptrace(PTRACE_TRACEME, 0, NULL, NULL);
      execlp(arg, arg, NULL);
      printf("Fail execlp\n");
      return;
    }
  else
    trace_prog(pid);
}
